package com.patrol.controller;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patrol.config.MyPasswordEncoder;
import com.patrol.dao.UserDao;
import com.patrol.pojo.TaskPoint;
import com.patrol.pojo.User;
import com.patrol.pojo.Xglx;
import com.patrol.service.TaskPointService;
import com.patrol.service.UserService;
import com.patrol.service.WorkerService;
import com.patrol.utils.*;
import io.netty.util.internal.StringUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.catalina.Host;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.util.ClassUtils;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.*;

/**
 * @author zsc
 * @description: 用户管理接口
 */
@CrossOrigin
@Api(tags = "系统用户接口")
@RestController
@RequestMapping("/api/user")
public class UserController {

    @Value("${patrol.path.upload}")
    private String uploadPath;

    @Resource
    private UserService userService;

    @Resource
    private MyPasswordEncoder myPasswordEncoder;

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private HostHolder hostHolder;

    @Resource
    private UserDao userDao;

    @Resource
    private TaskPointService taskPointService;

    @Resource
    private WorkerService workerService;

    /**
     * 根据username查询用户
     * @param realName
     * @return
     */
    @ApiOperation(value = "根据username查询用户")
    @GetMapping("selectUserByName/{realName}")
    public Result selectUserByName(@PathVariable String realName){
        User user = userService.selectUserByrealName(realName);
        List<User> list = new ArrayList<>();
        list.add(user);
        return Result.ok(list);
    }

    /**
     * 根据ID查询用户
     * @param id
     * @return
     */
    @ApiOperation(value = "根据ID查询用户")
    @GetMapping("selectUserById/{id}")
    public Result selectUserById(@PathVariable Integer id){
        User user = userService.getById(id);
        return Result.ok(user);
    }

    /**
     * 分页查询用户
     * @param current 当前页
     * @param limit 每页记录数
     * @return
     *
     * 带条件查询
     * TODO
     */
    @ApiOperation(value = "分页查询用户")
    @PostMapping("findPagePoint/{current}/{limit}")
    public Result selectPagePoint(@PathVariable long current, @PathVariable long limit){
        Page<User> page = new Page<>(current,limit);
        Page<User> pageUser = userService.page(page);
        return Result.ok(pageUser);
    }

    /**u
     * 查询所有用户
     * @return
     */
    @ApiOperation(value = "查询所有用户")
    @GetMapping("selectAll")
    public Result selectAll(){
        List<User> userList = userService.list();
        return Result.ok(userList);
    }

    /**
     * 查询所有的巡更人员
     * @param
     * @return
     */
    @ApiOperation(value = "查询所有的巡更人员")
    @GetMapping("selectAllXG")
    public Result selectAllXG(){
        List<User> list = userService.selectAllXG();
        return Result.ok(list);
    }

    /**
     * 根据ID删除用户
     * @param id
     * @return
     */
    @ApiOperation(value = "根据ID删除用户")
    @DeleteMapping("{id}")
    public Result deleteUserById(@PathVariable Integer id){
        boolean flag = userService.deleteUserById(id);
        if (flag){
            return Result.ok(200);
        }else {
            return Result.fail();
        }
    }

    /**
     * 批量逻辑删除用户
     * @param idList
     * @return
     */
    @ApiOperation(value = "批量逻辑删除用户")
    @DeleteMapping("batchRemove")
    public Result batchRemoveUser(@RequestBody List<Long> idList){
        userService.removeByIds(idList);
        return Result.ok();
    }

    /**
     * 根据ID修改用户信息
     * @param user
     * @return
     */
    @ApiOperation(value = "根据ID修改用户信息")
    @PostMapping("updateUser")
    public Result updateUserById(@RequestBody User user){
        boolean flag = userService.updateById(user);
        if (flag){
            return Result.ok(200);
        }else {
            return Result.fail();
        }
    }

    /**
     * 添加用户
     * @param user
     * @return
     */
    @ApiOperation(value = "添加用户")
    @PostMapping("insertUser")
    public Result insertUser(@RequestBody User user){
        user.setIsDeleted(0);
        user.setIsAssigned(0);
        boolean flag = userService.save(user);
        if (flag){
            return Result.ok(200);
        }else {
            return Result.fail();
        }
    }

    @ApiOperation(value = "获取登录用户信息")
    @GetMapping("/getUserInformation")
    public Result<User> getUserInformation(HttpServletRequest request) {
        String username = (String) request.getSession().getAttribute("LoginUser");
        User adminUser = userService.getUserInformation(username);
        return Result.ok(adminUser);
    }

    @ApiOperation(value = "修改登录用户信息")
    @PutMapping("/setUserInformation")
    public Result getAdminUser(User user) {
        // String username = (String) request.getSession().getAttribute("LoginUser");
        String username = user.getUsername();
        boolean b = userService.setUserInformation(user);
        if (b) {
            return Result.ok();
        }
        return Result.fail();
    }

    /**
     * 获取登录用户名
     */
    @ApiOperation(value = "获取用户头像url")
    @GetMapping("/getImageUrl/{username}")
    public Result getImageUrl(@PathVariable String username) {
        String url = userService.getImgUrl(username);
        List<String> list = new ArrayList<>();
        list.add(url);
        return Result.ok(list);
    }

    //验证账号密码
    //获取参数，账号，密码
    @ApiOperation(value = "用户注册")
    @PostMapping("/register")
    public Result register(@RequestParam("username") String username,
                           @RequestParam("password") String password) {

        // 判断username是否为空，该方法为空返回true
        if (StringUtil.isNullOrEmpty(username) || StringUtil.isNullOrEmpty(password)) {
            return Result.fail("用户名或者密码不能为空");
        }

        //有BUG
//        if (!RegexUtil.isLetterDigit(username)) {
//            return Result.fail("用户名只能含有数字和字母");
//        }

        boolean b = userService.registerAdminUser(username, password);
        return b ? Result.ok() : Result.fail();
    }


    @GetMapping("/selectUsernameIsExist/{username}")
    public Result selectUsernameIsExist(@PathVariable String username) {
        if (StringUtil.isNullOrEmpty(username)) {
            return Result.fail("用户名不能为空！");
        }
        if (!RegexUtil.isLetterDigit(username)) {
            return Result.fail("用户名只能含有字母或者数字！");
        }
        boolean b = userService.selectUsernameIsExist(username);
        return b ? Result.ok("用户名可用") : Result.fail("用户名已存在");
    }

    @ApiOperation(value = "用户登录")
    @PostMapping("/login")
    //获取参数，账号，密码
    public Result login(@RequestParam("username") String username,
                        @RequestParam("password") String password) {

        if (StringUtil.isNullOrEmpty(username) || StringUtil.isNullOrEmpty(password)) {
            return Result.fail("用户名或者密码不能为空");
        }

//        if (!RegexUtil.isLetterDigit(username)) {
//            return Result.fail("用户名格式只能含有数字和字母");
//        }

        User user = userService.getUserInformation(username);

        if (user.getUsername() == null || user.getPassword() == null) {
            return Result.fail("用户名或密码错误");
        }

        if (!user.getPassword().equals(myPasswordEncoder.md5(password))) {
            return Result.fail("1111密码错误");
        }
        String token = JWTUtil.sign(user.getUsername(), user.getPassword());
        String username1 = JWTUtil.getUsername(token);
        return Result.ok(username1);
    }

    @ApiOperation(value = "巡更人员登录接口")
    @PostMapping("/xgLogin")
    public Result xgLogin(@RequestParam("username") String username,
                          @RequestParam("password") String password) {

        if (StringUtil.isNullOrEmpty(username) || StringUtil.isNullOrEmpty(password)) {
            return Result.fail("用户名或者密码不能为空");
        }

        User user = userService.getUserInformation(username);

        if (user.getUsername() == null || user.getPassword() == null) {
            return Result.fail("用户名或密码错误");
        }

        if (!user.getPassword().equals(password)) {
            return Result.fail("用户密码错误");
        }

        if (!user.getAuthority().equals(1)) {
            return Result.fail("用户权限错误");
        }

        hostHolder.setUser(user);

        System.out.println(hostHolder.getUser());
        return Result.ok(user);
    }

    @ApiOperation(value = "修改巡更人员信息")
    @PostMapping("/updateXGUser")
    public Result updateXGUser(@RequestParam("userId")Integer userId,
                               @RequestParam("username")String username,
                               @RequestParam("realName")String realName,
                               @RequestParam("sex")int sex,
                               @RequestParam("tel")String tel,
                               @RequestParam("email")String email) {
        User user = new User(userId,username,realName,sex,tel,email);
        boolean b = userService.updateById(user);
        if (b){
            User user1 = userService.selectUserById(String.valueOf(userId));
            return Result.ok(user1);
        }
        return Result.fail();
    }

    @ApiOperation(value = "查询该巡更人员任务点")
    @GetMapping("/selectRWPoint/{userId}")
    public Result selectRWPoint(@PathVariable Integer userId) {
        List<TaskPoint> taskPoints = new ArrayList<>();
        List<Integer> pointIds = taskPointService.findPointIds(userId);
        for (int i=0;i<pointIds.size();i++){
            TaskPoint taskPoint = taskPointService.selectPointById(pointIds.get(i));
            int state = taskPointService.selectUserRWPointState(userId, pointIds.get(i));
            String state11 = null;
            if(state==0){
                state11 = "未完成";
            }else {
                state11 = "已完成";
            }
            Map<String,Object> param = new HashMap<>();
            //0-未完成  1-已完成
            param.put("state",state11);
            taskPoint.setParam(param);
            taskPoints.add(taskPoint);
        }
        return Result.ok(taskPoints);
    }

    @ApiOperation(value = "管理员改变巡更人员派遣状态")
    @GetMapping("/updateXGUserState/{userId}")
    public Result updateXGUserState(@PathVariable String userId) {
        String overTime = workerService.selectRWOverTime(userId);
        String RWRedisKey = "userlocus:" + userId + ":" + overTime;
        List<Xglx> list = workerService.selectAllInRW(userId);
        for (int i=0;i<list.size();i++){
            String userXGLXRedisKey = "userlocus:" + userId + ":" + list.get(i).getStartTime() + ":" + list.get(i).getOverTime();
            List ll = redisTemplate.opsForList().range(userXGLXRedisKey,0,-1);
            for (int j=0;j<ll.size();j++){
                redisTemplate.opsForList().leftPush(RWRedisKey, ll.get(i));
            }
        }

        User user = userService.selectUserById(userId);
        user.setIsAssigned(0);
        userService.updateById(user);
        workerService.updateDQTaskSign(userId);
        taskPointService.updateTaskPointSign(userId);
        return Result.ok();
    }

    /**
     * 微信小程序上传头像接口
     *
     * @param
     * @return
     */
    @ApiOperation(value = "微信小程序上传头像接口")
    @PostMapping("/weixinSendImage")
    public Result fileUpload(@RequestParam("file") MultipartFile multipartFile, Integer userId) {
        Result result = new Result();
        FileUtil fu = new FileUtil();
        // 获取图片的名字, 使用UUID重命名文件
        String fileName = UUID.randomUUID().toString().replace("-", "") + "." + fu.getSuffix(multipartFile.getOriginalFilename());
        if (!multipartFile.isEmpty()) {
            String savePath = uploadPath;
            try {
                FileUtil.uploadFile(multipartFile.getBytes(), savePath, fileName);
                String path = "https://www.emergencyfire.top/api/worker/Info/" + fileName;
                boolean b = userService.xgUpdatePhotoUrl(userId, path);
                if (b){
                    result.setCode(200);
                    result.setMessage(path);
                    return result;
                }
                return Result.fail();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return Result.fail();
    }

    /**
     * 显示头像头像接口
     * @param
     * @return
     */
    @ApiOperation(value = "显示头像头像接口")
    @GetMapping("/weixinShowImage/{userId}")
    public Result showImage(@PathVariable String userId) {
        User user = userService.selectUserById(userId);
        return Result.ok(user.getImg());
    }


    /**
     * 在ShiroConfig中配置了退出登陆的接口路径 /api/user/logout
     */
//    @GetMapping("/admin/logout")
//    public Result logout() {
//        return Result.ok();
//    }

    @GetMapping("/selectUserByUserName/{username}")
    public Result selectUserByUserName(@PathVariable String username) {
        if (StringUtil.isNullOrEmpty(username)) {
            return Result.ok("系统异常，获取用户名失败");
        }
        User one = userService.selectUserByUserName(username);
        return null != one ? Result.ok(one) : Result.fail();
    }

    /**
     * 文件上传
     *
     * @param
     * @return
     * @throws IOException
     */
    @ApiOperation(value = "上传头像文件")
    @PostMapping("/getUserImage")
    public Result fileUpload(@RequestParam("file") MultipartFile multipartFile,
                             @RequestParam("username") String username) {

        if (StringUtil.isNullOrEmpty(username)) {
            return Result.fail("文件名不能为空！");
        }

        if (multipartFile == null) {
            return Result.fail("未选择要上传的文件");
        }

        FileUtil fu = new FileUtil();
        // 获取图片的名字, 使用UUID重命名文件
        String fileName = UUID.randomUUID().toString().replace("-", "") + "." + fu.getSuffix(multipartFile.getOriginalFilename());
        if (!multipartFile.isEmpty()) {
            //获取项目classes/static的地址
            String staticPath = ClassUtils.getDefaultClassLoader().getResource("static").getPath();
            // 图片存储目录
            String url_path = "head/";
            //图片保存路径目录
            String savePath = staticPath + "/" + url_path;
            System.out.println("图片保存地址：" + savePath + fileName);
            // 访问路径=静态资源路径+文件目录路径
            String visitPath = "static/" + url_path;
            System.out.println("图片访问uri：" + visitPath + fileName);
            // 文件夹地址 + 名字 = 图片的路径
            String fileAddress = url_path + fileName;
            try {
                // 把图片前端访问静态路径head/...写入数据库
                User user = new User();
                user.setImg(fileAddress);
                user.setUsername(username);
                boolean b = userService.headerImageUpload(user, staticPath);
                if (b) {
                    // 图片上传的工具类
                    // 参数一：图片的编码格式的字节数组
                    // 参数二：图片存放的文件夹地址
                    // 参数三：图片的名字
                    FileUtil.uploadFile(multipartFile.getBytes(), savePath, fileName);
                    return Result.ok();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return Result.fail();
    }

    @ApiOperation(value = "查询巡更人员状态")
    @GetMapping("/selectXGUserStatus/{userId}")
    public Result selectXGUserStatus(@PathVariable Integer userId) {
        int i = userService.selectXGUserStatus(userId);
        return Result.ok(i);
    }
}
